from selenium import webdriver
from selenium.common import TimeoutException, NoSuchElementException
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.remote.webdriver import WebDriver
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.wait import WebDriverWait


class BasePage:
    def __init__(self, driver: WebDriver = None):
        if driver is not None:
            self.driver = driver
        else:
            options = Options()
            options.debugger_address = '127.0.0.1:92222'
            self.driver = webdriver.Chrome(options=options)
        self.driver.implicitly_wait(1)

    # 点击操作，失败后重试
    def click(self, by, value, timeout=10, check_loc: tuple = None):
        def loop_click(driver):
            ele.click()
            return len(driver.find_elements(*check_loc)) > 0

        ele = self.find(by, value, timeout)
        if not check_loc:
            ele.click()
        else:
            WebDriverWait(self.driver, 5).until(loop_click)

    # 显示等待
    def find(self, by, value, timeout=0):
        try:
            WebDriverWait(self.driver, timeout).until(expected_conditions.visibility_of_element_located((by, value)))
        except TimeoutException:
            raise NoSuchElementException(f"{(by, value)}元素未找到")
        except Exception as e:
            raise RuntimeError(f"{(by, value)}元素定位失败,{e}")
        return self.driver.find_element(by, value)

    # 返回元素列表，超时未找到才会返回空列表
    def finds(self, by, value, timeout=5):
        try:
            WebDriverWait(self.driver, timeout).until(expected_conditions.visibility_of_element_located((by, value)))
        except TimeoutException:
            return []
        return self.driver.find_elements(by, value)

    # 等待元素出现
    def wait(self, by, value, timeout=10):
        try:
            WebDriverWait(self.driver, timeout).until(expected_conditions.visibility_of_element_located((by, value)))
        except TimeoutException:
            raise NoSuchElementException(f"{(by, value)}元素未找到")
        except Exception as e:
            raise RuntimeError(f"{(by, value)}元素定位失败,{e}")

    # 等待元素消失
    def wait_disappear(self, by, value, timeout=10):
        try:
            WebDriverWait(self.driver, timeout).until_not(
                expected_conditions.visibility_of_element_located((by, value)))
        except TimeoutException:
            raise RuntimeError(f"{(by, value)}元素未消失")
